/*
 * @Description: 字符串协议解析
 * @Version: 1.0
 * @Autor: lzc
 * @Date: 2021-09-15 14:12:35
 * @LastEditors: lzc
 * @LastEditTime: 2021-09-16 09:44:14
 */
#ifndef COMMAND_PARSE_H
#define COMMAND_PARSE_H

#include <stdint.h>  
#include "stdio.h" 
#include "stdlib.h"
#include "string.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define MSG_OUTPUT(...) my_putstr(__VA_ARGS__)
#define MSG_CMD_TYTES   20      //串口数据解析成函数名的最大长度
#define MSG_ARG_LEN     30      //协议中数据的最大长度
#define MSG_CMD_LEN     3       //协议中命令的最大长度
#define MSG_MAX_ARGS    3       //一个协议帧包含的命令数量,如cal poi pow
#define MSG_COUNT (sizeof(s_cmd_buf)/sizeof(s_cmd_buf[0]))

#define USING_RT_DEVICE_RX 0    //是否使用RTT的串口设备
enum MS
{
    MS_EOK,
    MS_EFULL,
    MS_ERROR,
}; 

typedef struct
{
    uint8_t cmd[3][4];
    uint8_t data[2][32];
} Cmd_Info_Type;

typedef struct
{
    uint8_t cmd[MSG_CMD_TYTES];
    uint8_t data[2][30];
} myCmd_Info_Type;

typedef struct init_t
{
    uint8_t (*msg_port_fun)(myCmd_Info_Type info);
    char name[MSG_CMD_TYTES];
} _init_msg;

/**
* @function: Agreement_Type
* @description:  hex协议的结构体
*/
typedef struct
{
    uint8_t *data;  //协议的数据
    uint8_t status; //协议处理的状态，完成之后才能发送应答
    uint8_t type;   //串口协议判断，字符串或者是hex的协议
    uint16_t lens;  //协议的数据长度
} Agreement_Type;

/*
*状态枚举
*/
enum Status
{
    _agr_ready_status,   // 准备状态
    _agr_process_status, // 处理状态
    _agr_end_status,     // 完成状态
};

enum Type
{
    _agr_hex_type, // hex协议
    _agr_str_type, // 字符串协议
};

enum AGR
{
    AGR_OK,
    AGR_FULL,
    AGR_ERROR,
};


// 字符串解析方法 1
int communicate_parse(const char *data);
// 字符串解析方法 2
int msg_parse(const char *data);
char *get_Program_Time(char *buf);


#define _MSG_FUN(fn, level)                               \
  __attribute__((used)) const _init_msg _imp_##fn         \
      __attribute__((section(".msg_section." level))) = { \
          .msg_port_fun = fn,                             \
          .name = #fn,                                    \
  }


#define IMPORT_MSG_FUN(fn) _MSG_FUN(fn, "0")

extern void my_putstr(const char *str, ...);
extern unsigned char help(void);
extern uint8_t msg_idn_fun(Cmd_Info_Type x);
extern uint8_t msg_ver_fun(Cmd_Info_Type x);
extern uint8_t msg_rst_fun(Cmd_Info_Type x);
extern uint8_t msg_sys_upgrade_fun(Cmd_Info_Type x);
extern uint8_t msg_set_wavelength_fun(Cmd_Info_Type x);
extern uint8_t msg_set_power_fun(Cmd_Info_Type x);
extern uint8_t msg_set_linear_reset_fun(Cmd_Info_Type x);
extern uint8_t msg_set_coeff_reset_fun(Cmd_Info_Type x);
extern uint8_t msg_set_switch_fun(Cmd_Info_Type x);

extern uint8_t msg_get_wavelength_fun(Cmd_Info_Type x);
extern uint8_t msg_get_power_fun(Cmd_Info_Type x);
extern uint8_t msg_get_history_fun(Cmd_Info_Type x);

extern uint8_t msg_cal_start_fun(Cmd_Info_Type x);
extern uint8_t msg_cal_stop_fun(Cmd_Info_Type x);
extern uint8_t msg_cal_save_fun(Cmd_Info_Type x);
extern uint8_t msg_cal_level_fun(Cmd_Info_Type x);
extern uint8_t msg_cal_point_power_fun(Cmd_Info_Type x);
extern uint8_t msg_sys_screen_fun(Cmd_Info_Type x);
extern uint8_t msg_set_idn_fun(Cmd_Info_Type x);
extern uint8_t msg_set_btname_fun(Cmd_Info_Type x);

// 需要和下方对应
static const char *const s_cmd_buf[][MSG_MAX_ARGS] =
{
    {"idn", "\0", "\0"},
    {"ver", "\0", "\0"},
    {"rst", "\0", "\0"},
    {"set", "wav", "\0"},
    {"set", "pow", "\0"},
    {"set", "lin", "res"},
    {"set", "coe", "res"},
    {"set", "swi", "\0"},
    {"set", "idn", "\0"},
    {"set", "btn", "\0"},
    {"get", "wav", "\0"},
    {"get", "pow", "\0"},
    {"get", "his", "\0"},
    {"cal", "poi", "pow"},
    {"cal", "sta", "\0"},
    {"cal", "sto", "\0"},
    {"cal", "sav", "\0"},
    {"cal", "lev", "\0"},
    {"sys", "upg", "\0"},
    {"sys", "scr", "\0"},
};

/*命令处理函数*/
static uint8_t ( * const cmd_deal_port[MSG_COUNT])(Cmd_Info_Type x) =
{
    msg_idn_fun,
    msg_ver_fun,
    msg_rst_fun,
    msg_set_wavelength_fun,
    msg_set_power_fun,
    msg_set_linear_reset_fun,
    msg_set_coeff_reset_fun,
    msg_set_switch_fun,
    msg_set_idn_fun,
    msg_set_btname_fun,
    msg_get_wavelength_fun,
    msg_get_power_fun,
    msg_get_history_fun,
    msg_cal_point_power_fun,
    msg_cal_start_fun,
    msg_cal_stop_fun,
    msg_cal_save_fun,
    msg_cal_level_fun,
    msg_sys_upgrade_fun,
    msg_sys_screen_fun,
};


#ifdef __cplusplus
}
#endif

#endif
